package uts.sdk.modules.zeroFirebase

import io.dcloud.uts.UTSAndroid
import io.dcloud.uts.console

import androidx.credentials.CredentialManager
import androidx.credentials.GetCredentialRequest
import androidx.credentials.exceptions.GetCredentialException
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.Firebase
import com.google.firebase.FirebaseNetworkException
import com.google.firebase.FirebaseOptions
import com.google.firebase.FirebaseTooManyRequestsException
import com.google.firebase.auth.FirebaseAuthActionCodeException
import com.google.firebase.auth.FirebaseAuthEmailException
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException
import com.google.firebase.auth.FirebaseAuthInvalidUserException
import com.google.firebase.auth.FirebaseAuthUserCollisionException
import com.google.firebase.auth.GoogleAuthProvider
import com.google.firebase.auth.auth
import com.google.firebase.initialize
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

object NativeCode {
    private val coroutineScope = CoroutineScope(Dispatchers.IO)
    private var isInitialized = false
    private var auth: FirebaseAuth?= null
    private val projectId = "adfasf-9ae1f"  
    private val applicationId = "1:53580511109:android:68a246ce726b84d67af3f0"
    private val apiKey = "AIzaSyB7g4mn0x8TVKLUmJOCasdas8NbearrpI"
    private val storageBucket = "adfasf-9ae1f.firebasestorage.app"
    private val webClientId = "53580557009-adfasf0kcgjchtlbjud5mquco02pf4lpt.apps.googleusercontent.com"
	
    /**
     * credentialManager 要求必须在协程环境进行调用
     */
    private var credentialManager: CredentialManager?= null

    fun initializeFirebase() {
        if (!isInitialized) {
            val firebaseOptions = FirebaseOptions.Builder()
                .setProjectId(projectId)
                .setApplicationId(applicationId)
                .setApiKey(apiKey)
                .setStorageBucket(storageBucket)
                .build()
            Firebase.initialize(UTSAndroid.getAppContext()!!, firebaseOptions)
            auth = Firebase.auth
            isInitialized = true
            credentialManager = CredentialManager.create(UTSAndroid.getUniActivity()!!);
        }
    }

    fun signInGoogle(options: CallKotlinOptions) {
        initializeFirebase()
        coroutineScope.launch {
            try {
                val googleSignInOption = GetSignInWithGoogleOption.Builder(webClientId)
                    .build()
                val request = GetCredentialRequest.Builder()
                    .addCredentialOption(googleSignInOption)
                    .build();
                val result = credentialManager!!.getCredential(
                    context = UTSAndroid.getUniActivity()!!,
                    request = request
                )
                val credential = result.credential
                // Create Google ID Token
                val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)

                // Sign in to Firebase with using the token
                val credential1 = GoogleAuthProvider.getCredential(googleIdTokenCredential.idToken, null)
                auth!!.signInWithCredential(credential1)
                    .addOnCompleteListener(UTSAndroid.getUniActivity()!!) { task ->
                        if (task.isSuccessful) {
                            val user = auth!!.currentUser
                            user?.getIdToken(false) // true 表示强制刷新token，false 表示使用缓存的token
                                ?.addOnCompleteListener { task ->
                                    if (task.isSuccessful) {
                                        val idToken = task.result?.token
                                        val info = ZeroSuccess(
                                            code = 0,
                                            message = idToken!!
                                        )
                                        options.success(info)
                                        // 可以将token发送到你的服务器
                                    } else {
                                        // 处理错误
                                        options.fail(handleInError(task.exception))
                                    }
                                }
                        } else {
                            // If sign in fails, display a message to the user
                            options.fail(handleInError(task.exception))
                        }
                    }
            } catch (e: Exception) {
                options.fail(handleInError(e))
            }
        }
    }

    // 邮箱注册
    fun registEmail(email: String, password: String, options: CallKotlinOptions) {
        initializeFirebase()
        auth!!.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(UTSAndroid.getUniActivity()!!) { task ->
                if (task.isSuccessful()) {
                    // 注册成功,发送邮箱验证
                    auth!!.currentUser?.sendEmailVerification()
                        ?.addOnCompleteListener { task1 ->
                            if (task1.isSuccessful) {
                                //成功
                                val info = ZeroSuccess(
                                    code = 0,
                                    message = "success"
                                )
                                options.success(info)
                            } else {
                                options.fail(handleInError(task.exception))
                            }
                        } ?: options.fail(handleInError(null))
                } else {
                    options.fail(handleInError(task.exception))
                }
            }
    }

    // 邮箱登录
    fun loginEmail(email: String, password: String, options: CallKotlinOptions) {
        initializeFirebase()
        auth!!.signInWithEmailAndPassword(email, password)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    if (auth!!.currentUser?.isEmailVerified == true) {
                        //成功
                        val user = auth!!.currentUser
                        user?.getIdToken(false) // true 表示强制刷新token，false 表示使用缓存的token
                            ?.addOnCompleteListener { task ->
                                if (task.isSuccessful) {
                                    val idToken = task.result?.token
                                    val info = ZeroSuccess(
                                        code = 0,
                                        message = idToken!!
                                    )
                                    options.success(info)
                                    // 可以将token发送到你的服务器
                                } else {
                                    // 处理错误
                                    options.fail(handleInError(task.exception))
                                }
                            }
                    } else {
                        val error = ZeroError()
                        error.code = "12345"
                        error.type = "network.error.emailNotVerified"
                        error.message = "Email not verified"
                        options.fail(error)
                    }
                } else {
                    options.fail(handleInError(task.exception))
                }
            }
    }

    // 发送密码重置邮件
    fun sendPasswordResetEmail(email: String, options: CallKotlinOptions) {
        initializeFirebase()
        auth!!.sendPasswordResetEmail(email)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    //成功
                    val info = ZeroSuccess(
                        code = 0,
                        message = "success"
                    )
                    options.success(info)
                } else {
                    options.fail(handleInError(task.exception))
                }
            }
    }

    private fun handleInError(e: Exception?): ZeroError {
        val error = ZeroError()
        error.code = "-1"
        error.message = e?.message
        error.type = "network.error.-1"
        when (e) {
            is FirebaseAuthInvalidCredentialsException -> {
                error.code = e.errorCode
                error.type = "login.passwordError"
            }
            is FirebaseAuthUserCollisionException -> {
                error.code = e.errorCode
                error.type = "network.error.emailExist"
            }
            is FirebaseAuthInvalidUserException -> {
                error.code = e.errorCode
                error.type = "network.error.userNotExist"
            }
            is FirebaseAuthEmailException -> {
                error.code = e.errorCode
                error.type = "network.error.emailError"
            }
            is FirebaseAuthActionCodeException -> {
                error.code = e.errorCode
                error.type = "network.error.actionCodeError"
            }
            is FirebaseNetworkException -> {
                error.type = "network.error"
                error.message = e.localizedMessage
            }
            is FirebaseTooManyRequestsException -> {
                error.type = "network.error.10009"
                error.message = e.localizedMessage
            }
            is GetCredentialException -> {
                when (e.type) {
                    "android.credentials.GetCredentialException.TYPE_USER_CANCELED" -> {
                        error.type = "network.error.userCancel"
                    }
                    else -> {
                        error.message = "未知异常"
                    }
                }
            }
            else -> {
                error.message = "未知异常"
            }
        }
        return error
    }
}
